package com.yangfan.screenshot.log;

import android.content.Context;
import android.os.Process;
import android.text.TextUtils;
import android.util.Log;

import java.io.File;

/**
 * @author : yangfan_rj
 * @date   : 2022/12/7-14:16
 * desc   :
 */
public class LogUtil {

    private static ILogger mPrintLogger;

    private static ILogger mFileLogger;

    private static LogConfig mLogConfig;

    private static boolean mForceOpenFileLogger = true;

    public static void init(Context context) {
        if(context == null){
            throw new NullPointerException("context not allowed null");
        }

        mLogConfig = initLogConfig(context);
        init(mLogConfig);
    }

    private static void init(LogConfig config) {
        mLogConfig = config;
        if(mLogConfig != null
                && !TextUtils.isEmpty(mLogConfig.getLogFilePath())){
            mFileLogger = new FileLogger(mLogConfig.getLogFilePath());
        }

        mPrintLogger = new PrintLogger();
    }

    public static void forceOpenFileLogger() {
        mForceOpenFileLogger = true;
    }

    private static LogConfig initLogConfig(Context context) {
        String logPath = null;
        try{
            logPath = context.getCacheDir()
                    + File.separator + "log"
                    + File.separator;
        } catch(Exception e) {
            e.printStackTrace();
        }

        Log.d("LogUtil","logPath = " + logPath);

        if (TextUtils.isEmpty(logPath)) {
            return new LogConfig.Builder()
                    .setLogLevel(Log.VERBOSE)
                    .showLog(true)
                    .writeToFile(false)
                    .build();
        }

        return new LogConfig.Builder()
                .setLogFilePath(logPath)
                .setLogLevel(Log.VERBOSE)
                .showLog(true)
                .writeToFile(true)
                .build();
    }

    private static boolean isWriteToFile() {
        if(mLogConfig == null ||
                (mLogConfig != null && TextUtils.isEmpty(mLogConfig.getLogFilePath()))){
            return false;
        }

        return mLogConfig.isWriteToFile() || mForceOpenFileLogger;
    }

    private static boolean isShowLog(int logLevel) {
        if(mLogConfig == null){
            return false;
        }

        return mLogConfig.isShowLog() && mLogConfig.getLogLevel() <= logLevel;
    }

    public static void wtf(String tag, String message) {
        wtf(tag, message, false);
    }

    public static void d(String tag, String message) {
        d(tag, message, false);
    }

    public static void i(String tag, String message) {
        i(tag, message, false);
    }

    public static void w(String tag, String message) {
        w(tag, message, false);
    }

    public static void e(String tag, String message) {
        e(tag, message, false);
    }

    public static void e(String tag, Throwable throwable) {
        e(tag, Log.getStackTraceString(throwable), false);
    }

    public static void v(String tag, String message) {
        v(tag, message, false);
    }

    public static void v(String tag, String message, boolean forceWrite) {
        if (!isShowLog(Log.VERBOSE)) return;
        mPrintLogger.v(tag, message);
        if (isWriteToFile() || forceWrite) {
            mFileLogger.v(tag, Process.myPid()+":"+Thread.currentThread().getId()+" "+message);
        }
    }

    public static void d(String tag, String message, boolean forceWrite) {
        if (!isShowLog(Log.DEBUG)) return;
        mPrintLogger.d(tag, message);
        if (isWriteToFile() || forceWrite) {
            mFileLogger.d(tag, Process.myPid()+":"+Thread.currentThread().getId()+" "+message);
        }
    }

    public static void e(String tag, String message, boolean forceWrite) {
        if (!isShowLog(Log.ERROR)) return;
        mPrintLogger.e(tag, message);
        if (isWriteToFile() || forceWrite) {
            mFileLogger.e(tag, Process.myPid()+":"+Thread.currentThread().getId()+" "+message);
        }
    }

    public static void w(String tag, String message, boolean forceWrite) {
        if (!isShowLog(Log.WARN)) return;
        mPrintLogger.w(tag, message);
        if (isWriteToFile() || forceWrite) {
            mFileLogger.w(tag, Process.myPid()+":"+Thread.currentThread().getId()+" "+message);
        }
    }

    public static void i(String tag, String message, boolean forceWrite) {
        if (!isShowLog(Log.INFO)) return;
        mPrintLogger.i(tag, message);
        if (isWriteToFile() || forceWrite) {
            mFileLogger.i(tag, Process.myPid()+":"+Thread.currentThread().getId()+" "+message);
        }
    }

    public static void wtf(String tag, String message, boolean forceWrite) {
        if (!isShowLog(Log.ASSERT)) return;
        mPrintLogger.wtf(tag, message);
        if (isWriteToFile() || forceWrite) {
            mFileLogger.wtf(tag, Process.myPid()+":"+Thread.currentThread().getId()+" "+message);
        }
    }
}
